package com.xinqiupark.technology.ui.activity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.xinqiupark.technology.R;
import com.xinqiupark.technology.entity.House;

import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Subscriber;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.functions.Func2;
import rx.observables.GroupedObservable;

public class RxJavaActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_java);
    }

    public void createClick(View view) {
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello");
                subscriber.onNext("Hi");
                subscriber.onNext("Aloha");
                subscriber.onCompleted();
            }
        });
        observable.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("-->>" + s);
            }
        });
    }

    public void justClick(View view) {
        //Just()---最多10个数据
        Observable<String> observable = Observable.just("Hello", "Hi", "Aloha");
    // 将会依次调用：
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();`
        observable.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("-->>" + s);
            }
        });
    }

    /**
     * - from()---集合
     */
    public void fromClick(View view)
    {
        String[] words={"Hello", "Hi", "Aloha"};
        Observable<String> observable = Observable.from(words);
        // 将会依次调用：
// onNext("Hello");
// onNext("Hi");
// onNext("Aloha");
// onCompleted();
        observable.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("-->>" + s);
            }
        });
    }

    /**
     * - defer（）
     * [x]     just操作符是在创建Observable就进行了赋值操作
     - [x] defer是在订阅者订阅时才创建Observable，此时才进行真正的赋值操作
     - [x]  defer好处：在某些情况下，等待直到最后一分钟（就是知道订阅发生时）才生成Observable可以确保Observable包含最新的数据。
     */
    String i="11";
    public void deferClick(View view)
    {
        Observable<String> defer = Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {
                return Observable.just( i ) ;
            }
        }) ;

        Observable<String> test = Observable.just( i ) ;

        i="12";

        defer.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                Log.v( "rx_defer  " , "" + s ) ;
            }
        }) ;

        test.subscribe(new Action1<String>() {
            @Override
            public void call(String o) {
                Log.v( "rx_just " , "" + o ) ;
            }
        }) ;
    }

    /**
     *  // 事件加工
     >### **转化操作符**
     */
   public void mapClick(View view)
   {
        Observable.just(1,2,3,4)
                .map(new Func1<Integer, String>() {
                    @Override
                    public String call(Integer integer) {
                        return "this is"+integer;
                    }
                }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("-->>"+s);
            }
        });
   }

    /**
     * ####  flatMap  一对多转换/数据是无序的
     flatMap()中返回的是Observable对象（所以多用于网络嵌套）
     */
    public void flatMapClick(View view)
    {
        // 步骤1：创建Retrofit对象
//        Retrofit retrofit = new Retrofit.Builder()
//                .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
//                .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
//                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
//                .build();
//
//        // 步骤2：创建 网络请求接口 的实例
//        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
//
//        // 步骤3：采用Observable<...>形式 对 2个网络请求 进行封装
//        observable1 = request.getCall();
//        observable2 = request.getCall_2();
//
//
//        observable1.subscribeOn(Schedulers.io())               // （初始被观察者）切换到IO线程进行网络请求1
//                .observeOn(AndroidSchedulers.mainThread())  // （新观察者）切换到主线程 处理网络请求1的结果
//                .doOnNext(new Consumer<Translation1>() {
//                    @Override
//                    public void accept(Translation1 result) throws Exception {
//                        Log.d(TAG, "第1次网络请求成功");
//                        result.show();
//                        // 对第1次网络请求返回的结果进行操作 = 显示翻译结果
//                    }
//                })
//
//                .observeOn(Schedulers.io())                 // （新被观察者，同时也是新观察者）切换到IO线程去发起登录请求
//                // 特别注意：因为flatMap是对初始被观察者作变换，所以对于旧被观察者，它是新观察者，所以通过observeOn切换线程
//                // 但对于初始观察者，它则是新的被观察者
//                .flatMap(new Function<Translation1, ObservableSource<Translation2>>() { // 作变换，即作嵌套网络请求
//                    @Override
//                    public ObservableSource<Translation2> apply(Translation1 result) throws Exception {
//                        // 将网络请求1转换成网络请求2，即发送网络请求2
//                        return observable2;
//                    }
//                })
//
//                .observeOn(AndroidSchedulers.mainThread())  // （初始观察者）切换到主线程 处理网络请求2的结果
//                .subscribe(new Consumer<Translation2>() {
//                    @Override
//                    public void accept(Translation2 result) throws Exception {
//                        Log.d(TAG, "第2次网络请求成功");
//                        result.show();
//                        // 对第2次网络请求返回的结果进行操作 = 显示翻译结果
//                    }
//                }, new Consumer<Throwable>() {
//                    @Override
//                    public void accept(Throwable throwable) throws Exception {
//                        System.out.println("登录失败");
//                    }
//                });
    }

    /**
     * ### scan：累加操作符
     */
    public void scanClick(View view)
    {
        Observable.just(1,2,3,4)
                    .scan(new Func2<Integer, Integer, Integer>() {
                        @Override
                        public Integer call(Integer integer, Integer integer2) {
                            return integer+integer2;
                        }
                    }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("--->>"+integer);
            }
        });
    }

    /***
     * ### concatMap flatMapIterable

     - concatMap：concatMap()解决了flatMap()的交叉问题，它能够把发射的值连续在一起
     - flatMapIterable：flatMapIterable()和flatMap()几乎是一样的，不同的是flatMapIterable()它转化的多个Observable是使用Iterable作为源数据的。

     flatMapIterable代码示例：
     ```
     Observable.from(communities)
     .flatMapIterable(new Func1<Community, Iterable<House>>() {
    @Override
    public Iterable<House> call(Community community) {
    return community.houses;
    }
    })
     .subscribe(new Action1<House>() {

    @Override
    public void call(House house) {

    }
    });
     */

    /**
     * 将原始Observable发射的数据按照key来拆分成一些小的Observable，然后这些小Observable分别发射其所包含的的数据
     */
    public void groupByClick(View view)
    {
        List<House> houses=new ArrayList<>();
        houses.add(new House("中粮·海景壹号", "中粮海景壹号新出大平层！总价4500W起"));
        houses.add(new House("竹园新村", "满五唯一，黄金地段"));
        houses.add(new House("中粮·海景壹号", "毗邻汤臣一品"));
        houses.add(new House("竹园新村", "顶层户型，两室一厅"));
        houses.add(new House("中粮·海景壹号", "南北通透，豪华五房"));

        Observable<GroupedObservable<String,House>> groupByCommunityNameObservable=Observable.from(houses)
                .groupBy(new Func1<House, String>() {
                    @Override
                    public String call(House house) {
                        return house.getCommunityName();
                    }
                });

        Observable.concat(groupByCommunityNameObservable)
                    .subscribe(new Action1<House>() {
                        @Override
                        public void call(House house) {
                            System.out.println("--->>"+house);
                        }
                    });
    }

    /**
     * >### **过滤操作符**
     ### Filter：
     条件过滤操作符
     */
    public void FilterClick(View view)
    {
        Observable<Integer> observable = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        final Observable<Integer> filter = observable.filter(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                return integer > 4;
            }
        });
        filter.subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer o) {
                System.out.println("filter-- " + o);
            }
        });
    }

    /**
     * ### 消息数量过滤操作符的使用
     - take ：取前n个数据
     - takeLast：取后n个数据
     - first 只发送第一个数据
     - last 只发送最后一个数据
     - skip() 跳过前n个数据发送后面的数据
     - skipLast() 跳过最后n个数据，发送前面的数据
     */

    public void takeClick(View view)
    {
        //take 发送前3个数据
        Observable<Integer> observable = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable.take( 3 )
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "take-- " +  o );
                    }
                })   ;

        //takeLast 发送最后三个数据
        Observable<Integer> observable2 = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable2.takeLast( 3 )
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "takeLast-- " +  o );
                    }
                })   ;

        //first 只发送第一个数据
        Observable<Integer> observable3 = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable3.first()
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "first-- " +  o );
                    }
                })   ;

        //last 只发送最后一个数据
        Observable<Integer> observable4 = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable4.last()
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "last-- " +  o );
                    }
                })   ;

        //skip() 跳过前2个数据发送后面的数据
        Observable<Integer> observable5 = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable5.skip( 2 )
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "skip-- " +  o );
                    }
                })   ;

        //skipLast() 跳过最后两个数据，发送前面的数据
        Observable<Integer> observable6 = Observable.just( 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
        observable5.skipLast( 2 )
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer o) {
                        System.out.println( "skipLast-- " +  o );
                    }
                });
    }
}
